package com.example.rabc.service.impl;

import com.example.rabc.dao.PermissionRepository;
import com.example.rabc.dao.RoleRepository;
import com.example.rabc.exception.BusinessException;
import com.example.rabc.entity.Permission;
import com.example.rabc.entity.Role;
import com.example.rabc.monitor.Monitored;
import com.example.rabc.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 角色服务实现类
 */
@Service
@Transactional
public class RoleServiceImpl implements RoleService {
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private PermissionRepository permissionRepository;

    /**
     * 创建角色
     * @param role 角色实体
     * @param permissionCodes 权限代码列表
     * @return 创建的角色实体
     */
    @Override
    @Monitored
    public Role createRole(Role role, Set<String> permissionCodes) {
        if (roleRepository.existsByRoleCode(role.getRoleCode())) {
            throw new BusinessException("角色代码已存在");
        }
        
        // 设置权限
        if (permissionCodes != null && !permissionCodes.isEmpty()) {
            Set<Permission> permissions = permissionCodes.stream()
                .map(code -> permissionRepository.findByPermissionCode(code)
                    .orElseThrow(() -> new BusinessException("权限不存在: " + code)))
                .collect(Collectors.toSet());
            role.setPermissions(permissions);
        }
        
        return roleRepository.save(role);
    }

    /**
     * 更新角色
     * @param roleId 角色ID
     * @param role 角色实体
     * @param permissionCodes 权限代码列表
     * @return 更新后的角色实体
     */
    @Override
    @Monitored
    public Role updateRole(Long roleId, Role role, Set<String> permissionCodes) {
        Role existingRole = roleRepository.findById(roleId)
            .orElseThrow(() -> new BusinessException("角色不存在"));

        // 检查角色代码是否已存在（如果尝试更改角色代码）
        if (role.getRoleCode() != null && !role.getRoleCode().equals(existingRole.getRoleCode())) {
            if (roleRepository.existsByRoleCode(role.getRoleCode())) {
                throw new BusinessException("角色代码已存在");
            }
            // 更新角色代码
            existingRole.setRoleCode(role.getRoleCode());
        }
        
        // 更新角色信息
        existingRole.setRoleName(role.getRoleName());
        existingRole.setDescription(role.getDescription());
        existingRole.setStatus(role.getStatus());
        
        // 更新权限
        if (permissionCodes != null) {
            Set<Permission> permissions = permissionCodes.stream()
                .map(code -> permissionRepository.findByPermissionCode(code)
                    .orElseThrow(() -> new BusinessException("权限不存在: " + code)))
                .collect(Collectors.toSet());
            existingRole.getPermissions().clear();
            existingRole.getPermissions().addAll(permissions);
        }
        
        return roleRepository.save(existingRole);
    }

    /**
     * 删除角色
     * @param roleId 角色ID
     */
    @Override
    @Monitored
    public void deleteRole(Long roleId) {
        if (!roleRepository.existsById(roleId)) {
            throw new BusinessException("角色不存在");
        }
        roleRepository.deleteById(roleId);
    }

     /**
     * 根据ID获取角色
     * @param roleId 角色ID
     * @return 角色实体
     */
    @Override
    @Monitored
    @Transactional(readOnly = true)
    public Role getRoleById(Long roleId) {
        return roleRepository.findById(roleId)
            .orElseThrow(() -> new BusinessException("角色不存在"));
    }

     /**
     * 根据角色代码获取角色
     * @param roleCode 角色代码
     * @return 角色实体
     */
    @Override
    @Monitored
    @Transactional(readOnly = true)
    public Role getRoleByCode(String roleCode) {
        return roleRepository.findByRoleCode(roleCode)
            .orElseThrow(() -> new BusinessException("角色不存在"));
    }

     /**
     * 获取所有角色
     * @return 角色实体列表
     */
    @Override
    @Monitored
    @Transactional(readOnly = true)
    public List<Role> getAllRoles() {
        return roleRepository.findAll();
    }

     /**
     * 获取所有激活角色
     * @return 角色实体列表
     */
    @Override
    @Monitored
    @Transactional(readOnly = true)
    public List<Role> getActiveRoles() {
        return roleRepository.findByStatus(1);
    }

     /**
     * 为角色分配权限
     * @param roleId 角色ID
     * @param permissionCodes 权限代码列表
     * @return 是否成功分配权限
     */
    @Override
    @Monitored
    public boolean assignPermissionsToRole(Long roleId, Set<String> permissionCodes) {
        Role role = roleRepository.findById(roleId)
            .orElseThrow(() -> new BusinessException("角色不存在"));
        
        Set<Permission> permissions = permissionCodes.stream()
            .map(code -> permissionRepository.findByPermissionCode(code)
                .orElseThrow(() -> new BusinessException("权限不存在: " + code)))
            .collect(Collectors.toSet());
        
        role.getPermissions().addAll(permissions);
        roleRepository.save(role);
        return true;
    }

     /**
     * 从角色中移除权限
     * @param roleId 角色ID
     * @param permissionCodes 权限代码列表
     * @return 是否成功移除权限
     */
    @Override
    @Monitored
    public boolean removePermissionsFromRole(Long roleId, Set<String> permissionCodes) {
        Role role = roleRepository.findById(roleId)
            .orElseThrow(() -> new BusinessException("角色不存在"));
        
        Set<Permission> permissionsToRemove = permissionCodes.stream()
            .map(code -> permissionRepository.findByPermissionCode(code)
                .orElseThrow(() -> new BusinessException("权限不存在: " + code)))
            .collect(Collectors.toSet());
        
        role.getPermissions().removeAll(permissionsToRemove);
        roleRepository.save(role);
        return true;
    }
}